package com.way.demo.filter;

import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSONObject;
import com.way.demo.service.TestService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Map;

/**
 * @author lipingwei
 * @create 2021-01-21 16:02
 *
 * filter 无法通过注解@Autowired 注入bean，所以调用service方法，
 * ??？需要通过方法，getBean的方式，得到一个bean对象
 *  filter 中获取不到 post 请求body中的数据？？？
 *
 */
@Slf4j
@Component
public class MyFilter implements Filter {
   // @Autowired
   // TestService testServiceImpl;

    /**
     * token
     */
    private static final String TOKEN = "token";

    /**
     * source
     * 主要作用：开发阶段免token的校验
     * source = 0 时，开发阶段（本地联调测试），token 不做校验，token 为任意值
     * source = 1 时，生产测试阶段，token 校验
     */
    private static final String SOURCE = "source";
    private static final String UTF8 = "UTF-8";


    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
       log.info("filter 初始化====");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest)servletRequest;
        HttpServletResponse response= (HttpServletResponse)servletResponse;
        //请求方式：GET / POST
        String methodType = request.getMethod();
        /**
         * 设置编码
         */
        request.setCharacterEncoding(UTF8);
        response.setCharacterEncoding(UTF8);
        response.setContentType("application/json");
        /**
         * 获取 token 和 source
         */
        String token = request.getHeader(TOKEN);
        String source = request.getHeader(SOURCE);

        /**
         * 校验 token 与 source 如果有任意一个参数为空，则会提示错误
         */
//        if(StrUtil.isBlank(token)){
//            JSONObject res = new JSONObject();
//            res.put("code","-1");
//            res.put("success","false");
//
//                res.put("msg","token 不能为空");
//                response.getWriter().write(res.toJSONString());
//                log.error("token 不能为空");
//                return;
//
//        }
        boolean b = checkParam(token, source, response);
        if(b){
            return;
        }
        //获取请求中的参数，get,post请求中的参数都能获取到

        ServletRequest requestWrapper = null;
        if (request instanceof HttpServletRequest) {
            requestWrapper = new ReaderReuseHttpServletRequestWrapper2(request);
        }
        Map<String, Object> paramMap = HttpRequestUtil.getRequestParamMap(requestWrapper);


        //    Map<String, Object> paramMap = HttpRequestUtil.getRequestParamMap(request);

        //方式一：可以使用SpringUtil工具类获取bean对象，但由于SpringButil是引入的pom依赖第三方包，需要@improt(StringUtil.class) 注解导入
        //方式二： 可以直接将serviceBean 注入到filter (一般是选择第二种)
        // RespTestBo respTestBo = testServiceImpl.queryUserById(token, source);
       TestService testServiceImpl = (TestService) SpringUtil.getBean("testServiceImpl");
      //  RespTestBo respTestBo = testServiceImpl.queryUserById(token, source);
       // log.info("返回的用户信息=== {}",respTestBo);

        filterChain.doFilter(requestWrapper,response);

    }

    @Override
    public void destroy() {
        log.info("filter 销毁=====");
    }


    /**
     * 返回错误报文
     */
    private boolean checkParam(String token, String source,ServletResponse response) throws IOException {
        JSONObject res = new JSONObject();
        res.put("code","-1");
        res.put("success","false");
        if(StrUtil.isBlank(token)){
           res.put("msg","token 不能为空");
            response.getWriter().write(res.toJSONString());
            log.error("token 不能为空");
            return true;
        }
        if(StrUtil.isBlank(source)){
           res.put("msg","source 不能为空");
            response.getWriter().write(res.toJSONString());
            log.error("source 不能为空");
            return true;
        }
        return false;
    }

    /**
     * 在过滤器中获取 post请求body 中的数据
     */
  private Map<String,Object> getRequestBody(HttpServletRequest request) throws IOException {
      ReaderReuseHttpServletRequestWrapper requestWrapper = new ReaderReuseHttpServletRequestWrapper(request);
      String body = getBody(requestWrapper);

      return null;
   }

   private String getBody(HttpServletRequest request) {
       StringBuilder sb = new StringBuilder();
       try(ServletInputStream inputStream = request.getInputStream();
         BufferedReader reader=  new  BufferedReader(new InputStreamReader(inputStream,"UTF-8"))
         )
       {
         String line;
         while ((line = reader.readLine())!=null){
              sb.append(line);
         }
       } catch (IOException e) {
          log.error("get body error {}",e);
       }
      return sb.toString();
   }
}



